#include "p2pmessager.h"
QString P2PMessager::gap="===tcp package gap===";
P2PMessager::P2PMessager():connected(false),udpPort(21000),tcpPort(21001)
{
    NetWorker networker;
    myIp=networker.getIp();

    createTCPServer();
    findEachOther();
}

// 创建tcp server
void P2PMessager::createTCPServer()
{
    tcpServer=new QTcpServer(this);
    bool success=tcpServer->listen(QHostAddress::Any,tcpPort);
    qDebug()<<"创建TCPserver"<<(success?"成功":"失败");
    connect(tcpServer, SIGNAL(newConnection()),this, SLOT(newTCPConnection()));
}
// 发现彼此
void P2PMessager::findEachOther()
{
    udpSocket = new QUdpSocket(this);
    udpSocket->bind(QHostAddress::Any,udpPort);

    // socket 就绪后开始监听广播消息，即等等对方上线。
    connect(udpSocket, SIGNAL(readyRead()),this, SLOT(readUDPData()));

    // 发送广播消息，通知对方我上线了。
    this->broadCastOnLineMsg();
}

void P2PMessager::broadCastOnLineMsg(){
    QByteArray datagram = myIp.toUtf8();
    udpSocket->writeDatagram(datagram.data(), datagram.size(), QHostAddress::Broadcast, udpPort);
}

void P2PMessager::readUDPData()
{
    // 一直接收对方的连接请求，支持对方不停上下线
    while (udpSocket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(datagram.data(), datagram.size());
        QString ip=datagram.data();
        qDebug()<<(QString("收到广播消息 %1").arg(datagram.data()));

        if(ip==this->myIp){
            // 本机广播的消息，不做回应。
            continue;
        }else{
            // 如果当前是连接状态，则先断开之前的连接，再新建连接(支持对方不停上下线)。
            connected=false;
            delete tcpClientSocket;

            // 连接到对方的tcp server，告知本机ip，建立tcp双向连接。
            connectToTCPServer(ip);
            // 告知本机ip

            QJsonObject json;
            json.insert("type","connectToMe");
            json.insert("ip",myIp);
            send(QJsonDocument(json).toJson());


        }
    }
}
// 连接到对方tcp server
void P2PMessager::connectToTCPServer(QString ip){
    serverIp=ip;
    qDebug()<<(QString("连接上对方TCP server： %1").arg(serverIp));
    tcpClientSocket=new QTcpSocket();
    tcpClientSocket->connectToHost(serverIp,tcpPort);
    tcpClientSocket->waitForConnected();
    connected=true;
    if(tcpConnectionReadyCallback){
        tcpConnectionReadyCallback(this);
    }
}
void P2PMessager::newTCPConnection()
{
    //获取客户端连接
    tcpServerSocket = tcpServer->nextPendingConnection();
    //连接QTcpSocket的信号槽，以读取新数据
    QObject::connect(tcpServerSocket, &QTcpSocket::readyRead, this, &P2PMessager::readTCPData);
    QObject::connect(tcpServerSocket, &QTcpSocket::disconnected, this, &P2PMessager::disconnected);
    qDebug() << "A Client connect!";

}

void P2PMessager::readTCPData(){
    QByteArray buffer;
    //读取缓冲区数据
    buffer = tcpServerSocket->readAll();
    if(!buffer.isEmpty())
    {

        QString str = QString(buffer);
        QStringList packageList=str.split(P2PMessager::gap);
        foreach(QString package,packageList){
            if(package==""){
                continue;
            }
            qDebug()<<"接收到tcp数据："<<package;
            QJsonDocument json=QJsonDocument::fromJson(package.toUtf8());
            QJsonObject jsonObj= json.object();
            QString type=jsonObj.take("type").toString();
            if(type=="connectToMe")
            {
                QString ip=jsonObj.take("ip").toString();
                connectToTCPServer(ip);
            }
            // 执行回调函数
            if(tcpReceiveMessageCallback){
                tcpReceiveMessageCallback(package);
            }
        }

    }

}
void P2PMessager::disconnected(){
    connected=false;
    qDebug()<<"断开连接";
}

void P2PMessager::ready(simpleCallback fun){

    tcpConnectionReadyCallback=fun;
}
void P2PMessager::send(QString message){
    qDebug()<<"发送消息："<< message;
    QByteArray data=message.toUtf8();
    tcpClientSocket->write(data,data.length());
    tcpClientSocket->write(P2PMessager::gap.toUtf8());
    tcpClientSocket->flush();
}
void P2PMessager::listen(callback fun){

    tcpReceiveMessageCallback=fun;
}
